package order

import (
	"context"
	"github.com/gin-gonic/gin"
	"github.com/smartwalle/alipay/v3"
	"go.uber.org/zap"
	"net/http"
	"shop_webs/order_web/api"
	"shop_webs/order_web/forms"
	"shop_webs/order_web/global"
	"shop_webs/order_web/models"
	"shop_webs/order_web/proto"
	"strconv"
)

func List(ctx *gin.Context) {
	//订单列表
	userId := ctx.GetInt("userId")
	claims, _ := ctx.Get("claims")

	currentUser := claims.(models.MyClaims)
	zap.S().Infof("当前用户是%d,权限是%d", userId, currentUser.AuthorityId)
	var orderFilterRequest proto.OrderFilterRequest
	if currentUser.AuthorityId == 1 {
		orderFilterRequest.UserId = int32(userId)
	}

	pages := ctx.DefaultQuery("p", "0")
	pagesInt, _ := strconv.Atoi(pages)
	pageNum := ctx.DefaultQuery("pnum", "0")
	pageNumInt, _ := strconv.Atoi(pageNum)

	orderFilterRequest.Pages = int32(pagesInt)
	orderFilterRequest.PagePerNums = int32(pageNumInt)
	rsp, err := global.OrderClient.OrderList(context.Background(), &orderFilterRequest)
	if err != nil {
		zap.S().Errorw("[List] 查询 【订单列表】失败", "msg", err.Error())
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}
	if rsp.Total == 0 {
		ctx.JSON(http.StatusOK, gin.H{
			"total": 0,
		})
		return
	}

	/*		前端格式
			{
				"total":12,
				"data":[
					{
						"id":1,
						"goods_id":421,
						"goods_name":421,
						"goods_price":421,
						"goods_image":421,
						"nums":421,
						"checked":421,
					}
				]
			}
	*/
	var orderList []map[string]interface{}
	for _, order := range rsp.Data {
		orderList = append(orderList, map[string]interface{}{
			"id":       order.Id,
			"user":     order.UserId,
			"status":   order.Status,
			"post":     order.Post,
			"total":    order.Total,
			"address":  order.Address,
			"name":     order.SignerName,
			"mobile":   order.SingerMobile,
			"order_sn": order.OrderSn,
			"add_time": order.AddTime,
		})
	}

	ctx.JSON(http.StatusOK, gin.H{
		"total": rsp.Total,
		"data":  orderList,
	})
}
func Detail(ctx *gin.Context) {
	//订单详情
	id := ctx.Param("id")
	i, err := strconv.Atoi(id)
	if err != nil {
		ctx.JSON(http.StatusNotFound, gin.H{
			"msg": "url格式出错",
		})
		return
	}

	userId := ctx.GetInt("userId")
	claims, _ := ctx.Get("claims")
	currentUser := claims.(models.MyClaims)
	orderRequest := proto.OrderRequest{
		Id: int32(i),
	}
	//如果是管理员用户则返回所有的订单
	if currentUser.AuthorityId == 1 {
		orderRequest.UserId = int32(userId)
	}

	rsp, err := global.OrderClient.OrderDetail(context.Background(), &orderRequest)
	if err != nil {
		zap.S().Errorw("获取订单详情失败")
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}

	rspMap := make(map[string]interface{})
	rspMap["id"] = rsp.OrderInfo.Id
	rspMap["user"] = rsp.OrderInfo.UserId
	rspMap["status"] = rsp.OrderInfo.Status
	rspMap["user"] = rsp.OrderInfo.UserId
	rspMap["post"] = rsp.OrderInfo.Post
	rspMap["total"] = rsp.OrderInfo.Total
	rspMap["address"] = rsp.OrderInfo.Address
	rspMap["name"] = rsp.OrderInfo.SignerName
	rspMap["mobile"] = rsp.OrderInfo.SingerMobile
	rspMap["pay_type"] = rsp.OrderInfo.PayType
	rspMap["order_sn"] = rsp.OrderInfo.OrderSn
	rspMap["add_time"] = rsp.OrderInfo.AddTime
	goodList := make([]interface{}, 0)
	for _, item := range rsp.Goods {
		goodList = append(goodList, map[string]interface{}{
			"id":    item.Id,
			"name":  item.GoodsName,
			"image": item.GoodsImage,
			"price": item.GoodsPrice,
			"nums":  item.Nums,
		})
	}

	url, err := generateAlipayUrl(rsp.OrderInfo)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
		})
		return
	}

	rspMap["alipay_url"] = url
	rspMap["goods"] = goodList
	ctx.JSON(http.StatusOK, rspMap)
}
func New(ctx *gin.Context) {
	//创建订单
	itemForm := forms.CreateOrderForm{}
	if err := ctx.ShouldBind(&itemForm); err != nil {
		api.HandleValidatorError(err, ctx)
		return
	}

	rsp, err := global.OrderClient.CreateOrder(context.WithValue(context.Background(), "ginContext", ctx),
		&proto.OrderRequest{
			UserId:       int32(ctx.GetInt("userId")),
			Address:      itemForm.Address,
			Post:         itemForm.Post,
			SingerMobile: itemForm.SingerMobile,
			SignerName:   itemForm.SignerName,
		})
	if err != nil {
		zap.S().Errorw("新建订单失败,err:", err.Error())
		api.HandleGrpcErrorToHttp(err, ctx)
		return
	}

	// todo 还需要返回支付宝的支付链接，后续再实现
	url, err := generateAlipayUrl(rsp)
	if err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{
			"msg": err.Error(),
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"id":         rsp.Id,
		"alipay_url": url,
	})
	return
}
func generateAlipayUrl(rsp *proto.OrderInfoResponse) (urlStr string, err error) {
	alipayCfg := global.ServerConfig.Alipay

	//生成支付宝的支付url
	client, err := alipay.New(alipayCfg.AppID, alipayCfg.PrivateKey, false)
	if err != nil {
		zap.S().Errorw("实例化支付宝失败")
		return
	}
	err = client.LoadAliPayPublicKey(alipayCfg.AliPublicKey)
	if err != nil {
		zap.S().Errorw("加载支付宝的公钥失败")
		return
	}
	p := alipay.TradePagePay{
		Trade: alipay.Trade{
			NotifyURL:   alipayCfg.NotifyURL, // 支付结果回调的url，注意内网穿透问题
			ReturnURL:   alipayCfg.ReturnURL, // 支付成功后倒计时结束跳转的页面
			Subject:     "生鲜订单" + rsp.OrderSn,
			OutTradeNo:  rsp.OrderSn,                                         //传递一个唯一单号
			TotalAmount: strconv.FormatFloat(float64(rsp.Total), 'f', 2, 64), //保留两位小数
			ProductCode: "FAST_INSTANT_TRADE_PAY",                            // page支付必须使用这个配置
		},
	}

	url, err := client.TradePagePay(p)
	if err != nil {
		zap.S().Errorw("生成支付url失败")
		return
	}
	return url.String(), nil
}
